refactor(agents): collapse per-task agents into flagship skills - #2995
refactor(agents): collapse per-task agents into flagship skills#2995kovtcharov wants to merge 6 commits into
Conversation
Thirteen agent packages are gone: code, routing, blender, sd, emr, analyst, browser, docqa, doc-search, fileio, summarize, jira, docker. Their capability now comes from the flagship agent's tool surface driven by a SKILL.md, which is where new capability belongs — a skill is a markdown file, an agent was a wheel with a manifest, CI, docs, and a publish slot. Most of them were never reachable: only email and gaia have a daemon sidecar spec or a launchable TUI catalog row, so the rest showed as "not published on the Agent Hub yet" and could not be installed at all. Several defined zero tools of their own and consisted entirely of a system prompt already covered by the flagship's 66 registered tools. Two new skills carry forward the prose worth keeping: file-ops (from fileio) and summarize (the style tables and fold-forward chunking from summarize's prompts.py). data-explore, research-report and document-brief already existed and cover analyst, browser and docqa/doc-search. Also removed as dead weight: the jira/summarize/docker standalone apps, the Blender MCP client/server pair, the Docker MCP server, the MCP bridge's jira/blender/summarize surfaces and the multipart upload path that only the summarize endpoint used, the bpy extra, and the blender/jira/docker Claude specialist definitions. Behaviour changes a user can see: - `gaia analyze|browse|summarize|blender|sd|jira|docker` and `gaia mcp docker` are gone, as are the gaia-code and gaia-emr console scripts. - `gaia api` exposes no models: AGENT_MODELS held one entry, the routing agent, which routed to the code agent. - hello-world, word-count and connectors-demo stay as teaching templates and are no longer catalog agents. Jira and Docker return as connectors, scoped in amd#2989 and amd#2990.
The starter-pack guard checks tools_required against the tools mixins register plus a short whitelist of the tools ChatAgent registers inline. The whitelist was missing request_user_input, so the new file-ops skill failed the guard for declaring a tool the flagship really does register — asking the user before a destructive write is the whole point of that skill. Verified the same way as the rest of the list: the `def` must exist in the chat agent's source, so a rename drops the name instead of silently passing.
`gaia api` started but served nothing: its model map held one entry, the routing agent, which routed to the code agent — both deleted. It now exposes the flagship as the model `gaia`, so any OpenAI-compatible client (VSCode, curl, an SDK) drives the agent that actually ships. Verified end to end: /v1/models lists it, the agent constructs with the SSE handler installed, and an unknown model still 404s with an actionable message. That needed one plumbing fix: ChatAgentConfig never forwarded `output_handler` to the base Agent, so there was no way to hand a ChatAgent the SSE handler the API server streams through. Also stopped three commands describing things that no longer exist: - `gaia download --list` advertised Code/Blender/Jira/Docker agent profiles. The SD entry stays but is relabelled — the SD tool mixin is still here, the standalone agent is not. - `gaia init --profile code` installed models for a deleted agent. - The MCP bridge advertised `gaia.eval`, which nothing has ever implemented — it was the last entry in the manifest with no handler behind it. Docs updated to match: the API reference, spec, SDK page and VSCode guide all said the model list was empty by default.
`execute_python_file` runs a .py file in a subprocess — arbitrary code execution — but it was the one dangerous tool missing from the confirmation gate. `run_shell_command` sits behind both the gate AND a read-only command allowlist; this had neither, so it was the weakest link in the set. It mattered little while the OpenAI-compatible server exposed nothing. Now that it serves the flagship, an unattended caller reaches a 61-tool agent, so the gap closes here. Verified: the tool is refused and the file does not run. Also from review of this branch: - Dropped `python-multipart` from core install_requires. It was there because the MCP bridge imported it at module load to parse multipart uploads for the summarize endpoint; that endpoint and the import are gone, and nothing else under src/ imports it. It stays in the `api` and `ui` extras, which do. - Removed `send_sse_headers` and `stream_sse` from the bridge — the deleted summarize endpoint was their only caller. - Corrected an ApiAgent docstring that claimed `GaiaAgent -> gaia`; the default it documents would produce `gaia-gaia`, and the flagship is served under the `gaia` key in AGENT_MODELS instead.
The one that mattered: deleting the browse/analyze branch left its trailing `agent.close()` behind, stitched into the chat branch's cleanup one level too deep — inside `except Exception: pass`. Neither ChatAgent nor the base Agent has a `close()`, and the `hasattr` guard that used to protect it went with the deleted block, so a `gaia chat` run where `stop_watching()` raised would have turned a graceful exit into an AttributeError escaping the `finally` and hiding the original error. Also swept the tree for that whole bug class (a statement stranded after `pass`, an unreachable statement after `return`) — nothing else. The summarize skill told the model to pass `summary_type` values the tool rejects. `summarize_document` validates against exactly brief/detailed/bullets, while the skill named `executive`, `action_items`, `participants` and friends in backticks — inherited from the deleted agent, which validated those itself. The most natural transcript ask, "what were the action items", would have returned an error instead of a summary. The style vocabulary stays as prose guidance; the skill now says which three values are real. `GET /v1/models` built a full agent just to read two integers off it. That was cheap when the entry was the routing agent and expensive now that it is the flagship, whose constructor opens RAG, scratchpad and memory handles and an HTTP session — on an endpoint clients poll at startup. It now checks the class and only instantiates an actual ApiAgent: 291ms first call, 2ms after, no handles. Smaller: `gaia init --profile` advertised `code` in argparse choices after the profile was deleted; the `sd` profile's quick-start printed `gaia sd`, a command this branch removed; `gaia download`'s epilog demoed `--agent code`; a `wait_for_user` helper whose only caller was a Blender demo; scripts/jira_smoke.py imported two deleted modules; and assorted docstrings, menu strings and plan-doc links still pointed at agents that no longer exist.
Verdict: Request changesThis collapses roughly fourteen per-task agents (code, analyst, browser, jira, docker, blender, sd, summarize, emr, docqa, routing, fileio, doc-search) into skills the flagship agent loads on demand, leaving The one genuinely new piece of logic here has no test. The change that lets the API server hand the flagship agent its streaming output handler is what makes The Blender workshop notebook is now dead. It walks a reader through installing a Blender add-on from a file this PR deletes, and imports a module that no longer exists. Delete it alongside the rest of the Blender surface (the workshop index mentions it too), or mark it as removed. Real-world evidenceNo evidence bundle was produced for this run, and the shell and 🔍 Technical detailsIssues Found🟡 New
One test in 🟡 Three live references to removed modules:
CLAUDE.md's rule is that a functional change updates every doc that describes it. Nits🟢 Garbled comment ( 🟢 Garbled docstring ( 🟢 Import smoke-check no longer covers the flagship ( The list drops every per-task agent (correct) but keeps only Same list exists in 🟢 Stale CI summary line ( Still echoes Strengths
|
GAIA shipped 19 agent packages and a user could reach two of them. Everything except
emailand thegaiaflagship showed in the TUI as "not published on the Agent Hub yet" — no daemon sidecar spec, no launchable catalog row, no install path. Meanwhile several of those packages defined zero tools of their own: they were a system prompt wrapped in a wheel, and the prompt described tools the flagship already registers.This deletes thirteen of them and moves the part worth keeping — the procedural knowledge — into
SKILL.mdfiles the flagship loads on demand. Adding a capability is now writing markdown, not shipping a package with a manifest, a CI workflow, a publish slot, and a docs page. Net: -98,000 lines.Deleted:
code,routing,blender,sd,emr,analyst,browser,docqa,doc-search,fileio,summarize,jira,docker. Kept:gaia(flagship),chat(its base class),email, plushello-world/word-count/connectors-demoas teaching templates that are no longer catalog agents.Two new skills carry the deleted prose forward —
file-opsandsummarize(its style tables and fold-forward chunking procedure).data-explore,research-reportanddocument-briefalready existed and cover analyst, browser and the two RAG duplicates.Jira and Docker come back as connectors — scoped in #2989 and #2990. Docker needs a security decision first:
docker buildexecutes arbitrary code, and GAIA only grants a skill shell access through a reviewed per-binary policy.What a user will notice
gaia analyze | browse | summarize | blender | sd | jira | dockerandgaia mcp dockerare gone, along with thegaia-codeandgaia-emrconsole scripts.gaia apinow exposes exactly one model,gaia— the flagship. Its map previously held one entry, the routing agent, which routed to the code agent; both are deleted, so the endpoint is now pointed at the agent that actually ships. Any OpenAI-compatible client (VSCode, curl, an SDK) works against it.gaia download --listandgaia init --profileno longer offer profiles for deleted agents, and the MCP bridge stopped advertisinggaia.eval, which nothing has ever implemented.🔍 Also removed, and why
Dead weight that only existed to serve a deleted agent:
src/gaia/apps/{jira,summarize,docker}— standalone apps importing deleted agent classes.src/gaia/mcp/blender_mcp_{client,server}.py— a Blender-addon socket protocol on port 9876, not MCP.src/gaia/mcp/servers/docker_mcp.py— a thin wrapper aroundDockerAgent.gaia.jira/gaia.blender.create/gaia.summarizetools and/jira/summarizeendpoints, plus the multipart-upload path only/summarizeused (mcp_bridge.py: 953 → 624 lines).blenderextra (bpy), thedata-lite/web-litelegacy registry aliases, staleFRAMEWORK_PATHSentries that would have filtered a user's own frames out of their traceback, and the blender/jira/docker Claude specialist definitions.src/gaia/sd/mixin.pyis kept — image generation stays available on ChatAgent behind the existingenable_sd_toolsflag; only the standalone agent is gone.Docs: 38 pages deleted, 39 edited,
docs/docs.jsonpruned. All 194 nav entries verified to resolve to a real file.Test plan
python util/lint.py --all— clean, exit 0All 13 skills parse via
parse_skill_file, and every tool each one declares intools_requiredexists in the flagship's live registry (66 tools, 0 gaps) — verified by instantiatingGaiaAgentand diffing, sincetools_requiredis advisory and a gap fails mid-run rather than at loadgaia --helplists no deleted command; each removed command is rejected;gaia mcp --helphas nodockergaia api:/v1/modelsreturns an empty list and a request for a deleted model 404s with an actionable messageMCP bridge boots with 2 agents / 3 tools; a deleted tool returns a clean "not implemented"
gaia apiend to end:/v1/modelslistsgaia,registry.get_agent("gaia")builds the flagship with the SSE handler installed and 61 tools registered, and an unknown model 404s with an actionable messagecd tui && go build ./... && go test ./...— all packages passdocs/docs.json: 194 nav pages, 0 missing filespytest tests/unitfull run, compared against the same run on unmodifiedmain:Those failures are pre-existing and environmental: the sandbox this ran in blocks the loopback socket
asyncio.new_event_loop()needs on Windows, tripping the repo's hermetic-network guard (tests/unit/conftest.py, untouched here). A set-diff of failing node ids found exactly one genuine regression — the starter-skill guard rejectingrequest_user_input— fixed in the second commit. Every other difference reproduces identically onmainwhen run in isolation. The 30 fewer passes are tests deleted along with their agents.Launch the flagship in the TUI and exercise a collapsed capability end to end — e.g. load
data-exploreand confirm it callscreate_table/query_datainstead of fabricating. Needs a machine with Lemonade running; not done yet.Review notes
The riskiest edits are not the deletions — they are the three files that had a deleted agent threaded through shared logic:
src/gaia/cli.py(dispatch + parsers),src/gaia/mcp/mcp_bridge.py(tool routing), andtests/test_api.py(every request now 404s atmodel_existsbefore reaching validation, so the live-server success-path tests were removed rather than left to rot).